package cc.comac.mom.datahandlers.entity;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import cc.comac.mom.bean.EquipPatrolCheckPlan;
import cc.comac.mom.bean.EquipPatrolCheckPlanBean;
import cc.comac.mom.bean.EquipPatrolCheckWorkOrder;
import cc.comac.mom.bean.ResultDev;
import cc.comac.mom.dao.entity.EquipPatrolCheckPlanDao;
import cc.comac.mom.entity.EquipPatrolCheckPlanEntity;
import cc.comac.mom.entity.EquipPatrolCheckWorkOrderEntity;
import cc.comac.mom.redis.IdFactory;
import cc.comac.mom.util.BaseEntityDataUtil;
import cc.comac.mom.util.FrequencyUtil;
import cc.comac.mom.util.MomConstants;
import cc.comac.mom.util.ResultBean;
import cc.comac.mom.util.TimeUtil;

@Component
@Transactional
public class EquipPatrolCheckPlanDataHandler extends ServiceImpl<EquipPatrolCheckPlanDao, EquipPatrolCheckPlanEntity> {
	@Autowired
	private EquipPatrolCheckPlanDao equipPatrolCheckPlanDao;

	@Autowired 
	private EquipPatrolCheckWorkOrderDataHandler equipPatrolCheckWorkOrderDataHandler;
	@Autowired
	private BaseEntityDataUtil baseEntityDataUtil;
	
	@Resource
	private IdFactory idFactory;
	
	public ResultBean insert(EquipPatrolCheckPlan obj) {
		ResultBean resultBean = new ResultBean(true);
        ResultBean resultBean2 = this.checkData(obj);
        if(!resultBean2.success) {
        	return resultBean2;
        }
        EquipPatrolCheckPlanEntity innerData = obj.getInnerData();
		innerData.setPlanNumber(idFactory.generateEquipPatrolCheckPlanNo());
		innerData.setIsAlendar(0);//未到期
		baseEntityDataUtil.setBaseEntityData(innerData);
		int insert = equipPatrolCheckPlanDao.insert(innerData);
		if(insert<1) {
			throw new RuntimeException("保存巡检计划失败");
		}
		return resultBean;
	}

	// 批量删除数据
	public ResultBean delete(List<EquipPatrolCheckPlan> list) {
		ResultBean resultBean = new ResultBean(true);
		if (list.size() > 0) {
			List<Long> ids=new ArrayList<>();
			for(EquipPatrolCheckPlan e:list){
				ids.add(e.getInnerData().getId());
			}
			equipPatrolCheckPlanDao.batchUpdatePlanStatus(ids);
		}
		return resultBean;
	}

	//修改巡检计划
	public ResultBean update(EquipPatrolCheckPlan obj) {
		ResultBean resultBean = new ResultBean(true);
		ResultBean checkData = this.checkData(obj);
		if(!checkData.success) {
			return checkData;
		}
		EquipPatrolCheckPlanEntity innerData = obj.getInnerData();
		if(innerData.getStatus() == MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED) {
			resultBean.setErrorMessge("计划已发布，不允许修改");
			return resultBean;
		}
		baseEntityDataUtil.updateBaseEntityData(innerData);
		int updateById = equipPatrolCheckPlanDao.updateById(innerData);
		if(updateById<1) {
			throw new RuntimeException("修改巡检计划失败");
		}
		return resultBean;
	}
	//计划下发
	
	public ResultBean planIssue(List<EquipPatrolCheckPlanEntity> PlanEntityList) {
		ResultBean resultBean = new ResultBean(true);
		if(PlanEntityList == null || PlanEntityList.size()<1) {
			throw new RuntimeException("数据为空");
		}
		List<Long> collect = PlanEntityList.stream().map(EquipPatrolCheckPlanEntity::getId).collect(Collectors.toList());
		List<EquipPatrolCheckPlanEntity> selectBatchIds = equipPatrolCheckPlanDao.selectBatchIds(collect);
		if(selectBatchIds == null || selectBatchIds.size()<1){
			throw new RuntimeException("数据为空");
		}
		ArrayList<EquipPatrolCheckWorkOrder> listEquipPatrolCheckWorkOrder = new  ArrayList<EquipPatrolCheckWorkOrder>();
		for(EquipPatrolCheckPlanEntity item :selectBatchIds) {
			//已发布，不允许再次发布
			if(item.getStatus() == MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED) {
				throw new RuntimeException("该定检计划已经发布，不允许操作");
			}
			 LocalDateTime planStartData = null;
			 LocalDateTime nowData = LocalDateTime.now();
			//校验定检频率和周期是否符合
			int frequent = FrequencyUtil.getCycleDataToHouse(item.getFrequentType(), item.getFrequentValue());
			int executionHours = FrequencyUtil.getCycleDataToHouse(item.getExecutionTime(), item.getExecutionTimeValue());
			//首次开始日期
			LocalDateTime firstPlanStartData = TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate());
			//周期结束日期
			LocalDateTime cycleDataToDateTime = FrequencyUtil.getCycleDataToLocalDateTime(item.getCycle(), item.getCycleValue(),firstPlanStartData);
			
			
			//判断发布当天是否要生成工单
			   //发布日期在首个开始日期之前,且 不考虑工作日历
			if(nowData.isBefore(firstPlanStartData) && item.getIsAlendar() == 0) {
				item.setStatus(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED);
				item.setPlanStartDate(item.getFirstPlanStartDate());
				item.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(firstPlanStartData.plusHours(executionHours)));
				//发布日期在首次日期之前,当天生成工单,开始日期为首次日期
				EquipPatrolCheckWorkOrder equipPatrolCheckWorkOrder = new EquipPatrolCheckWorkOrder();
				EquipPatrolCheckWorkOrderEntity equipPatrolCheckWorkOrderEntity = new EquipPatrolCheckWorkOrderEntity();
				equipPatrolCheckWorkOrderEntity.setWorkNumber(idFactory.generateEquipPatrolCheckPlanOrderNo());
				equipPatrolCheckWorkOrderEntity.setPatrolCheckId(item.getId());
				equipPatrolCheckWorkOrderEntity.setDescription(item.getDescription());
				equipPatrolCheckWorkOrderEntity.setPlanNumber(item.getPlanNumber());
				equipPatrolCheckWorkOrderEntity.setFrequentType(item.getFrequentType());
				equipPatrolCheckWorkOrderEntity.setFrequentValue(item.getFrequentValue());
				equipPatrolCheckWorkOrderEntity.setCycle(item.getCycle());
				equipPatrolCheckWorkOrderEntity.setCycleValue(item.getCycleValue());
				equipPatrolCheckWorkOrderEntity.setExecuteUser(PlanEntityList.get(0).getExecuteUser());
				equipPatrolCheckWorkOrderEntity.setExecuteUserJobNumber(PlanEntityList.get(0).getExecuteUserJobNumber());
				equipPatrolCheckWorkOrderEntity.setIsAlendar(item.getIsAlendar());
				equipPatrolCheckWorkOrderEntity.setCalendarCode(item.getCalendarCode());
				equipPatrolCheckWorkOrderEntity.setPlanStartDate(item.getFirstPlanStartDate());
				equipPatrolCheckWorkOrderEntity.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate()).plusHours(executionHours)));
				equipPatrolCheckWorkOrderEntity.setLocation(item.getLocation());
				equipPatrolCheckWorkOrderEntity.setStatus(MomConstants.EQUIP_REGULAR_CHECK_ORDER_STATUS_NOEXECUTE);//待执行
				equipPatrolCheckWorkOrder.setInnerData(equipPatrolCheckWorkOrderEntity);
				listEquipPatrolCheckWorkOrder.add(equipPatrolCheckWorkOrder);
				continue;
			}else if(nowData.isBefore(firstPlanStartData) && item.getIsAlendar() != 0) {
				//考虑工作日历
				resultBean.setErrorMessge("计划单号:"+item.getPlanNumber()+"需要考虑工作日历");
				return resultBean;
			}else if(nowData.isAfter(firstPlanStartData) && item.getIsAlendar() == 0) {
				//发布日期在首个日期之后,生成下一个工单,且不考虑工作日历
				//
				for(int i =1 ;i<100000;i++) {
					planStartData = firstPlanStartData.plusHours(frequent*i);
					if(nowData.isBefore(planStartData)) {
						break;
					}else {
						continue;
					}
				}
				if(nowData.isBefore(planStartData)) {
					//此时planStartData就是下一个要生成的工单的开始日期
					if(planStartData.isAfter(cycleDataToDateTime)) {
						//已到期
						throw new RuntimeException("计划单号:"+item.getPlanNumber()+"已过期，不能下发");
					}else {
						item.setStatus(MomConstants.EQUIP_REGULAR_CHECK_PLAN_STATUS_ISSUED);
						item.setPlanStartDate(item.getFirstPlanStartDate());
						item.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(firstPlanStartData.plusHours(executionHours)));
						baseEntityDataUtil.updateBaseEntityData(item);
						//发布日期在首次日期之前,当天生成工单,开始日期为首次日期
						EquipPatrolCheckWorkOrder equipPatrolCheckWorkOrder = new EquipPatrolCheckWorkOrder();
						EquipPatrolCheckWorkOrderEntity equipPatrolCheckWorkOrderEntity = new EquipPatrolCheckWorkOrderEntity();
						equipPatrolCheckWorkOrderEntity.setWorkNumber(idFactory.generateEquipPatrolCheckPlanOrderNo());
						equipPatrolCheckWorkOrderEntity.setPatrolCheckId(item.getId());
						equipPatrolCheckWorkOrderEntity.setDescription(item.getDescription());
						equipPatrolCheckWorkOrderEntity.setPlanNumber(item.getPlanNumber());
						equipPatrolCheckWorkOrderEntity.setFrequentType(item.getFrequentType());
						equipPatrolCheckWorkOrderEntity.setFrequentValue(item.getFrequentValue());
						equipPatrolCheckWorkOrderEntity.setCycle(item.getCycle());
						equipPatrolCheckWorkOrderEntity.setCycleValue(item.getCycleValue());
						equipPatrolCheckWorkOrderEntity.setExecuteUser(item.getExecuteUser());
						equipPatrolCheckWorkOrderEntity.setExecuteUserJobNumber(item.getExecuteUserJobNumber());
						equipPatrolCheckWorkOrderEntity.setIsAlendar(item.getIsAlendar());
						equipPatrolCheckWorkOrderEntity.setCalendarCode(item.getCalendarCode());
						equipPatrolCheckWorkOrderEntity.setPlanStartDate(item.getFirstPlanStartDate());
						equipPatrolCheckWorkOrderEntity.setPlanEndDate(TimeUtil.fomatLocalDateTimeToDate(TimeUtil.fomatDateToLocalDateTime(item.getFirstPlanStartDate()).plusHours(executionHours)));
						equipPatrolCheckWorkOrderEntity.setLocation(item.getLocation());
						equipPatrolCheckWorkOrderEntity.setStatus(MomConstants.EQUIP_REGULAR_CHECK_ORDER_STATUS_NOEXECUTE);//待执行
						equipPatrolCheckWorkOrder.setInnerData(equipPatrolCheckWorkOrderEntity);
						listEquipPatrolCheckWorkOrder.add(equipPatrolCheckWorkOrder);
						continue;
					}
				}else {
					//已过期
					throw new RuntimeException("计划单号:"+item.getPlanNumber()+"已过期，不能下发");
				}
			}else if(nowData.isAfter(firstPlanStartData) && item.getIsAlendar() != 0) {
				//发布日期在首个日期之后,生成下一个工单,且考虑工作日历
				throw new RuntimeException("计划单号:"+item.getPlanNumber()+"需要考虑工作日历");
			}

		}
		String executeUser = PlanEntityList.get(0).getExecuteUser();
		String executeUserJobNumber = PlanEntityList.get(0).getExecuteUserJobNumber();
		selectBatchIds.forEach(item -> {
			item.setExecuteUser(executeUser);
			item.setExecuteUserJobNumber(executeUserJobNumber);
		});
		//执行批量下发
		boolean updateBatchById = this.updateBatchById(selectBatchIds);
		if(!updateBatchById) {
			throw new RuntimeException("计划下发失败！");
		}
		//执行批量生成工单
		ResultBean resultBean2 = equipPatrolCheckWorkOrderDataHandler.insertBatch(listEquipPatrolCheckWorkOrder);
		if(!resultBean2.success) {
			throw new RuntimeException(resultBean2.getMessage());
		}
		return resultBean;
	}
	//计划查询
	
	//查询
	public ResultDev selectByFields(EquipPatrolCheckPlanBean obj) {
		ResultDev resultDev = new ResultDev();
		if (obj.getPageSize() == 0) {
			obj.setPageSize(10);
		}
		obj.setPageNum((obj.getPageNum()-1)*obj.getPageSize());
		List<EquipPatrolCheckPlanBean> listEquipRegularCheckPlanBean = equipPatrolCheckPlanDao.selectByFields(obj);
		long countByFields = equipPatrolCheckPlanDao.selectCountByFields(obj);
		
		// 将查询总数除以每页数量后向上取整获取总页数
		double pageCount = Math.ceil((double)countByFields / obj.getPageSize());
		resultDev.setEntityList(listEquipRegularCheckPlanBean);
		resultDev.setPageCount((int)pageCount);
		resultDev.setTotalQuantity((int)countByFields);
		return resultDev;
	}
	//校验数据
	public ResultBean checkData(EquipPatrolCheckPlan obj) {
		ResultBean resultBean = new ResultBean(true);
		if(obj == null || obj.getInnerData() == null) {
			throw new RuntimeException("数据为空");
		}
		if(StringUtils.isEmpty(obj.getInnerData().getFrequentType()) || obj.getInnerData().getFrequentValue() <=0) {
			throw new RuntimeException("频率为空");
		}
		if(StringUtils.isEmpty(obj.getInnerData().getCycle()) || obj.getInnerData().getCycleValue() <=0) {
			throw new RuntimeException("循环周期为空");
		}
		if(obj.getInnerData().getFirstPlanStartDate() == null) {
			throw new RuntimeException("首次开始日期为空");
		}
		//校验定检频率和周期是否符合
		int frequent = FrequencyUtil.getCycleDataToHouse(obj.getInnerData().getFrequentType(), obj.getInnerData().getFrequentValue());
		int cycle = FrequencyUtil.getCycleDataToHouse(obj.getInnerData().getCycle(), obj.getInnerData().getCycleValue());
		if(frequent>cycle) {
			throw new RuntimeException("循环周期必须大于定检频率");
		}
		LocalDateTime cycleDataToDateTime = FrequencyUtil.getCycleDataToLocalDateTime(obj.getInnerData().getCycle(), obj.getInnerData().getCycleValue(), TimeUtil.fomatDateToLocalDateTime(obj.getInnerData().getFirstPlanStartDate()));
		LocalDateTime now = LocalDateTime.now();
		if(now.isAfter(cycleDataToDateTime)) {
			throw new RuntimeException("过期配置，请重新配置");
		}
		return resultBean;
	}
}
